package cleaner

import (
	"file-cleaner/internal/logger"
	"file-cleaner/internal/pkg/file_cleaner/file_info"
	"file-cleaner/internal/pkg/file_cleaner/queue"
	"fmt"
	"strings"
	"time"
)

type FileCleaner struct {
	queryQueue     queue.Queue
	cleanTaskQueue queue.Queue
	hashMap        map[string]*file_info.FileInfo
}

func NewFileCleaner(queryQueue queue.Queue, cleanTaskQueue queue.Queue) *FileCleaner {
	return &FileCleaner{
		queryQueue:     queryQueue,
		cleanTaskQueue: cleanTaskQueue,
		hashMap:        make(map[string]*file_info.FileInfo),
	}
}

func (c *FileCleaner) Run() {
	for {
		n := c.queryQueue.Size()
		for i := 0; i < n; i++ {
			if c.queryQueue.IsEmpty() {
				break
			}
			item := c.queryQueue.Poll()
			if item == queue.Done {
				c.cleanTaskQueue.Add(item)
				return
			}
			info, ok := item.(*file_info.FileInfo)
			if ok {
				c.publishCleanTask(info)
			} else {
				logger.Errorf("info(%v) type(%T) is not FileInfo", item, item)
			}
		}
		time.Sleep(time.Second)
	}
}

func (c *FileCleaner) publishCleanTask(info *file_info.FileInfo) {
	if strings.EqualFold(strings.TrimSpace(info.Hash()), "") {
		logger.Errorf("Failed to publish clean task, cased by: no hash for %v", info.Path())
		return
	}

	hash := fmt.Sprintf("%s_%d", info.Hash(), info.Size())
	targetInfo, has := c.hashMap[hash]
	if !has {
		c.hashMap[hash] = info
		targetInfo = info
	}
	c.cleanTaskQueue.Add(newCleanTaskInfo(info, targetInfo))
}
